home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
scheme
/
boxer
/
boxer.lha
/
bxfile.lisp
< prev
next >
Wrap
Text File
|
1993-07-17
|
15KB
|
392 lines
;; -*- Mode: LISP; PACKAGE: (BOXER GLOBAL 1000); BASE: 8.; FONTS: cptfont -*-
;;
;; (C) Copyright 1983-1985 Massachusetts Institute of Technology
;;
;; Permission to use, copy, modify, distribute, and sell this software
;; and its documentation for any purpose is hereby granted without fee,
;; provided that the above copyright notice appear in all copies and that
;; both that copyright notice and this permission notice appear in
;; supporting documentation, and that the name of M.I.T. not be used in
;; advertising or publicity pertaining to distribution of the software
;; without specific, written prior permission. M.I.T. makes no
;; representations about the suitability of this software for any
;; purpose. It is provided "as is" without express or implied warranty.
;;
;;
;; +-Data--+
;; This file is part of the | BOXER | system.
;; +-------+
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; THIS IS THE FILE SYSTEM INTERFACE FOR BOXER ;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; This file contains the top level interface between the BOXER file system and the rest
;;; of the BOXER system
;;; Most of the rest of this file contains old versions of the file system code so that OLD
;;; BOXER code can still be used.
;;; Low level conversion methods for boxes and rows (and chas)
;;; these functions convert between the current box representation and
;;; the two styles of file reprsentation for boxes/rows
;;; these two styles being: LIST-STYLE and ARRAY-STYLE
;;; BOX =====> FILE functions................
(DEFMETHOD (BOX :RETURN-INIT-PLIST-FOR-SAVING) ()
`(:TYPE ,(TELL SELF :TYPE)
:DISPLAY-STYLE-LIST ,DISPLAY-STYLE-LIST
:TRUE-NAME ,(UNLESS (NULL PORTS)
(PUTHASH SELF (INTERN (GENSYM)) *PORT-HASH-TABLE*))))
(DEFMETHOD (PORT-BOX :RETURN-INIT-PLIST-FOR-SAVING) ()
`(:TYPE ,(TELL SELF :TYPE)
:DISPLAY-STYLE-LIST ,DISPLAY-STYLE-LIST
:PORTED-TO-BOX ,(GETHASH PORTS *PORT-HASH-TABLE*)))
;;;rows are converted to leaderless arrays (or lists of chas/box-lists) for storage
(DEFMETHOD (ROW :RETURN-ARRAY-FOR-STORAGE) ()
(LET* ((LAST-CHA (CHAS-ARRAY-ACTIVE-LENGTH CHAS-ARRAY))
(ROW-STORAGE-ARRAY (MAKE-ARRAY LAST-CHA)))
(DO ((CHA-INDEX 0 (+ CHA-INDEX 1)))
((= CHA-INDEX LAST-CHA) ROW-STORAGE-ARRAY)
(ASET (IF (BOX? (AREF CHAS-ARRAY CHA-INDEX))
(TELL (AREF CHAS-ARRAY CHA-INDEX) :RETURN-ARRAY-FOR-STORAGE)
(AREF CHAS-ARRAY CHA-INDEX)) ;goes away when we flush chas
ROW-STORAGE-ARRAY
CHA-INDEX))))
(DEFMETHOD (ROW :RETURN-LIST-FOR-STORAGE) () ;is this faster ?
(MAPCAR (FUNCTION (LAMBDA (CHA) (IF (BOX? CHA)
(TELL CHA :RETURN-LIST-FOR-STORAGE)
CHA)))
(TELL SELF :CHAS)))
;;;boxes are converted to an array of row arrays with the init-plist-for-saving store in
;;;the leader of the array or a list of row lists with the plist as the car
(DEFMETHOD (BOX :RETURN-ARRAY-FOR-STORAGE) ()
(LET* ((LAST-ROW (TELL SELF :LENGTH-IN-ROWS))
(BOX-STORAGE-ARRAY (MAKE-ARRAY LAST-ROW
':LEADER-LIST
`(,(TELL SELF :RETURN-INIT-PLIST-FOR-SAVING)))))
(DO ((ROW-INDEX 0 (+ ROW-INDEX 1)))
((= ROW-INDEX LAST-ROW) BOX-STORAGE-ARRAY)
(ASET (TELL (TELL SELF :ROW-AT-ROW-NO ROW-INDEX) :RETURN-ARRAY-FOR-STORAGE)
BOX-STORAGE-ARRAY
ROW-INDEX))))
(DEFMETHOD (PORT-BOX :RETURN-ARRAY-FOR-STORAGE) ()
(MAKE-ARRAY 0 ':LEADER-LIST `(,(TELL SELF :RETURN-INIT-PLIST-FOR-SAVING))))
(DEFMETHOD (BOX :RETURN-LIST-FOR-STORAGE) ()
(CONS (TELL SELF :RETURN-INIT-PLIST-FOR-SAVING)
(MAPCAR (FUNCTION (LAMBDA (ROW) (TELL ROW :RETURN-LIST-FOR-STORAGE)))
(TELL SELF :ROWS))))
(DEFMETHOD (PORT-BOX :RETURN-LIST-FOR-STORAGE) ()
(CONS (TELL SELF :RETURN-INIT-PLIST-FOR-SAVING)
()))
;;;FILE =====> BOX functions................
(DEFMETHOD (BOX :INIT-FROM-FILE) (INIT-PLIST)
(SETQ ;;these come from box proper
CACHED-ROWS NIL
CACHED-CODE NIL
DISPLAY-STYLE-LIST (OR (GET INIT-PLIST ':DISPLAY-STYLE-LIST)
DISPLAY-STYLE-LIST))
(TELL SELF :SET-TYPE (OR (GET INIT-PLIST ':TYPE) ':DOIT-BOX))
(UNLESS (NULL (GET INIT-PLIST ':TRUE-NAME)) ;if there is a TRUE-NAME hash it with the box
(PUSH SELF *RENAME-QUEUE*) ;get a new name to avoid conflicts
(PUTHASH (GET INIT-PLIST ':TRUE-NAME) SELF *FILE-PORT-HASH-TABLE*)))
;(DEFMETHOD (GRAPHICS-BOX :INIT-FROM-FILE) (INIT-PLIST)
; (MULTIPLE-VALUE-BIND (IL IT IR IB)
; (WITH-FONT-MAP-BOUND (*BOXER-PANE*)
; (BOX-BORDERS-FN ':BORDER-WIDS ':GRAPHICS-BOX))
; (LET ((HOR-BORDER-SIZE (+ IL IR))
; (VER-BORDER-SIZE (+ IT IB)))
; (SETQ ;; These we inherit from chas.
; SUPERIOR-ROW (GET INIT-PLIST ':SUPERIOR-ROW)
; CHA-CODE ':BOX
; FONT-NO NIL
; ;; these we inherit from vanilla boxes
; FIRST-INFERIOR-ROW NIL
; CACHED-ROWS NIL
; CACHED-CODE NIL
; STATIC-VARIABLES-ALIST NIL
; DISPLAY-STYLE-LIST (OR (GET INIT-PLIST ':DISPLAY-STYLE-LIST)
; DISPLAY-STYLE-LIST)
; ;; and this is from the graphics box itself
; BIT-ARRAY (TV:MAKE-SHEET-BIT-ARRAY
; *BOXER-PANE*
; (- (CADR DISPLAY-STYLE-LIST) HOR-BORDER-SIZE)
; (- (CADDR DISPLAY-STYLE-LIST) VER-BORDER-SIZE)
; ':TYPE 'ART-1B
; ;; we need to store the actual desired width of the bit
; ;; array in the leader because TV:MAKE-SHEET-BIT-ARRAY
; ;; rounds up to the nearest multiple of 32 in order to
; ;; keep BITBLT happy
; ':LEADER-LIST `(,(- (CADR DISPLAY-STYLE-LIST) HOR-BORDER-SIZE)
; ,(- (CADDR DISPLAY-STYLE-LIST) VER-BORDER-SIZE)))))))
(DEFMETHOD (BOX :FILL-FROM-STORAGE-ARRAY) (STORAGE-ARRAY)
(LET ((NO-OF-ROWS (ARRAY-LENGTH STORAGE-ARRAY)))
(SETQ FIRST-INFERIOR-ROW (MAKE-A-ROW-FROM-ARRAY-STORAGE SELF (AREF STORAGE-ARRAY 0)))
(DOTIMES (ROW-NO (1- NO-OF-ROWS))
(TELL SELF :APPEND-ROW
(MAKE-A-ROW-FROM-ARRAY-STORAGE SELF (AREF STORAGE-ARRAY (1+ ROW-NO)))))))
(DEFMETHOD (BOX :FILL-FROM-STORAGE-LIST) (STORAGE-LIST) ;takes a list of rows (no plist)
(SETQ FIRST-INFERIOR-ROW (MAKE-A-ROW-FROM-LIST-STORAGE SELF (CAR STORAGE-LIST)))
(DOLIST (ROW-LIST (CDR STORAGE-LIST))
(TELL SELF :APPEND-ROW
(MAKE-A-ROW-FROM-LIST-STORAGE SELF ROW-LIST))))
(DEFMETHOD (PORT-BOX :FILL-FROM-STORAGE-ARRAY) (STORAGE-ARRAY)
STORAGE-ARRAY
NIL)
(DEFMETHOD (PORT-BOX :FILL-FROM-STORAGE-LIST) (STORAGE-LIST)
STORAGE-LIST
NIL)
(DEFUN MAKE-A-BOX-FROM-ARRAY-STORAGE (ROW-IT-IS-IN BOX-ARRAY
&OPTIONAL (BOX (MAKE-INSTANCE 'BOX)))
(LET* ((INIT-PLIST (LOCF (ARRAY-LEADER BOX-ARRAY 0))))
(TELL BOX :INIT-FROM-FILE INIT-PLIST)
(TELL BOX :SET-SUPERIOR-ROW ROW-IT-IS-IN)
(IF (PORT-BOX? BOX)
(IF (GETHASH (GET INIT-PLIST ':PORTED-TO-BOX) *FILE-PORT-HASH-TABLE*)
(TELL BOX :SET-PORT-TO-BOX
(GETHASH (GET INIT-PLIST ':PORTED-TO-BOX) *FILE-PORT-HASH-TABLE*))
(PUSH (CONS BOX (GET INIT-PLIST ':PORTED-TO-BOX))
*FILE-PORT-QUEUE*)) ;ported to box doesn't exist yet
(TELL BOX :FILL-FROM-STORAGE-ARRAY BOX-ARRAY)))
BOX)
(DEFUN MAKE-A-BOX-FROM-LIST-STORAGE (ROW-IT-IS-IN BOX-LIST
&OPTIONAL (BOX (MAKE-INSTANCE 'BOX)))
(LET* ((INIT-PLIST (LOCF (CAR BOX-LIST))))
(TELL BOX :SET-SUPERIOR-ROW ROW-IT-IS-IN)
(TELL BOX :INIT-FROM-FILE INIT-PLIST)
(WHEN (GRAPHICS-BOX? BOX)
(SETQ *ROW-CHAS-POINTER-ADJUST* T))
(IF (PORT-BOX? BOX)
(IF (GETHASH (GET INIT-PLIST ':PORTED-TO-BOX) *FILE-PORT-HASH-TABLE*)
(TELL BOX :SET-PORT-TO-BOX
(GETHASH (GET INIT-PLIST ':PORTED-TO-BOX) *FILE-PORT-HASH-TABLE*))
(PUSH (CONS BOX (GET INIT-PLIST ':PORTED-TO-BOX))
*FILE-PORT-QUEUE*)) ;ported to box doesn't exist yet
(TELL BOX :FILL-FROM-STORAGE-LIST (CDR BOX-LIST))))
BOX)
;;when chas get flushed, this should change todo the boxes in the array and then
;;do a copy array
(DEFMETHOD (ROW :FILL-FROM-STORAGE-ARRAY) (STORAGE-ARRAY)
(DOTIMES (CHA-NO (ARRAY-LENGTH STORAGE-ARRAY))
(IF (NUMBERP (AREF STORAGE-ARRAY CHA-NO))
(CHAS-ARRAY-INSERT-CHA CHAS-ARRAY
CHA-NO
(AREF STORAGE-ARRAY CHA-NO))
(CHAS-ARRAY-INSERT-CHA CHAS-ARRAY
CHA-NO
(MAKE-A-BOX-FROM-ARRAY-STORAGE SELF
(AREF STORAGE-ARRAY CHA-NO))))))
(DEFMETHOD (ROW :FILL-FROM-STORAGE-LIST) (STORAGE-LIST)
(LET ((*ROW-CHAS-POINTER-ADJUST* NIL))
(DOTIMES (CHA-NO (LENGTH STORAGE-LIST))
(IF (NUMBERP (NTH CHA-NO STORAGE-LIST))
(CHAS-ARRAY-INSERT-CHA CHAS-ARRAY
CHA-NO
(NTH CHA-NO STORAGE-LIST))
(CHAS-ARRAY-INSERT-CHA CHAS-ARRAY
CHA-NO
(MAKE-A-BOX-FROM-LIST-STORAGE SELF
(NTH CHA-NO STORAGE-LIST)))))
(WHEN *ROW-CHAS-POINTER-ADJUST*
(DOTIMES (I (TELL SELF :LENGTH-IN-CHAS))
(SETF (AREF CHAS-ARRAY I)
(FOLLOW-STRUCTURE-FORWARDING (AREF CHAS-ARRAY I)))))))
(DEFUN MAKE-A-ROW-FROM-ARRAY-STORAGE (BOX-IT-IS-IN ROW-ARRAY)
(LET ((NEW-ROW (MAKE-INSTANCE 'ROW)))
(TELL NEW-ROW :SET-SUPERIOR-BOX BOX-IT-IS-IN)
(TELL NEW-ROW :FILL-FROM-STORAGE-ARRAY ROW-ARRAY)
NEW-ROW))
(DEFUN MAKE-A-ROW-FROM-LIST-STORAGE (BOX-IT-IS-IN ROW-LIST)
(LET ((NEW-ROW (MAKE-INSTANCE 'ROW)))
(TELL NEW-ROW :SET-SUPERIOR-BOX BOX-IT-IS-IN)
(TELL NEW-ROW :FILL-FROM-STORAGE-LIST ROW-LIST)
NEW-ROW))
(DEFUN MAKE-A-CHA-FROM-STORAGE (CHA-CODE-NO)
(MAKE-CHA CHA-CODE-NO))
(DEFUN DO-QUEUED-PORTS ()
(DOLIST (PORT-WITH-DESTINATION *FILE-PORT-QUEUE*)
(TELL (CAR PORT-WITH-DESTINATION) :SET-PORT-TO-BOX
(GETHASH (CDR PORT-WITH-DESTINATION) *FILE-PORT-HASH-TABLE*))))
(COMMENT ;flush when the fasdumper works
(DEFUN RENAME-RENAME-QUEUE ()
(DOLIST (BOX-THAT-NEEDS-A-NEW-NAME *RENAME-QUEUE*)
(TELL BOX-THAT-NEEDS-A-NEW-NAME :CHANGE-TRUE-NAME)))
) ;to here
;;;Slow, portable save/read box....
(DEFUN SAVE-BOX-INTO-FILE-INTERNAL (BOX NAME)
(WITH-OPEN-FILE
(FILE-STREAM NAME ':OUT)
(FUNCALL FILE-STREAM ':LINE-OUT ";-*-MODE:BOXER; -*-")
(FUNCALL FILE-STREAM ':LINE-OUT "(SETQ *BOX-STORAGE-LIST* (QUOTE ")
(LET ((PACKAGE (PKG-FIND-PACKAGE 'BOXER))
(BASE 10.)
(IBASE 10.)
(*NOPOINT NIL))
(PRIN1 (TELL BOX :RETURN-LIST-FOR-STORAGE) FILE-STREAM))
(FUNCALL FILE-STREAM ':LINE-OUT "))"))
(CLRHASH *PORT-HASH-TABLE*)
':NOPRINT)
(DEFUN READ-FILE-INTO-BOX-INTERNAL (EMPTY-BOX NAME)
(LET ((BASE 10.)
(IBASE 10.)
(*NOPOINT NIL))
(READFILE NAME 'BOXER T))
;;the variable *BOX-STORAGE-LIST* is now defined
(MAKE-A-BOX-FROM-LIST-STORAGE (TELL EMPTY-BOX :SUPERIOR-ROW)
*BOX-STORAGE-LIST*
EMPTY-BOX)
(DO-QUEUED-PORTS) ;take care of any ports that have been deferred
(CLRHASH *FILE-PORT-HASH-TABLE*) ;clear hash table for next read
; (RENAME-RENAME-QUEUE) ;rename all boxes with names to avoid possible
(PROCESS-BOX-LOCAL-DEFINITIONS EMPTY-BOX)) ;name conflicts with already existing boxes
;;; The Top Level. This looks at the :byte-size property to determine if the file has been
;;; fasdumped or if it is a simple list
(DEFUN READ-FILE-INTO-BOX (EMPTY-BOX NAME)
(LET* ((PATHNAME (IF *STICKY-FILE-DEFAULTING?*
(SETQ *BOXER-PATHNAME-DEFAULT*
(FS:MERGE-PATHNAMES NAME *BOXER-PATHNAME-DEFAULT*))
(FS:MERGE-PATHNAMES NAME *BOXER-PATHNAME-DEFAULT*)))
(BYTE-SIZE (GET (FS:FILE-PROPERTIES PATHNAME) ':BYTE-SIZE)))
(IF (> BYTE-SIZE 7.)
(LOAD-BINARY-BOX-INTERNAL EMPTY-BOX PATHNAME)
(READ-FILE-INTO-BOX-INTERNAL EMPTY-BOX PATHNAME)))
(TELL EMPTY-BOX :MODIFIED))
(DEFUN SAVE-BOX-INTO-FILE (BOX FILENAME)
(LET ((PATHNAME (IF *STICKY-FILE-DEFAULTING?*
(SETQ *BOXER-PATHNAME-DEFAULT*
(FS:MERGE-PATHNAMES FILENAME *BOXER-PATHNAME-DEFAULT*))
(FS:MERGE-PATHNAMES FILENAME *BOXER-PATHNAME-DEFAULT*))))
(when (cl:probe-file pathname)
(cl:rename-file pathname
(cl:make-pathname :name
(cl:string
(string-append (send pathname :name)
"-OLD"))
:defaults
pathname)))
(IF *FASDUMP?*
(DUMP-TOP-LEVEL-BOX BOX PATHNAME)
(SAVE-BOX-INTO-FILE-INTERNAL BOX PATHNAME))))
(DEFUN INITIALIZE-BOXER-WORLD ()
(COND ((PROBEF (FS:INIT-FILE-PATHNAME "BOXER" :BIN))
(LOAD (FS:INIT-FILE-PATHNAME "BOXER" :BIN)))
((PROBEF (FS:INIT-FILE-PATHNAME "BOXER" :LISP))
(LOAD (FS:INIT-FILE-PATHNAME "BOXER" :LISP))))
(WHEN (PROBEF (FS:INIT-FILE-PATHNAME "BOXER" :BOX))
(LET ((*STICKY-FILE-DEFAULTING?* NIL))
(READ-FILE-INTO-BOX
*INITIAL-BOX*
(FS:INIT-FILE-PATHNAME "BOXER" :BOX)))))
(DEFUN INITIALIZE-BOXER-FROM-LISP ()
(WHEN (BOUNDP '*BOXER-PANE*)
(SETUP-EDITOR T)))
;;;stuff from streams--we need to keep this around so that we can load old
;;;boxer code
(DEFUN STREAM-COPY-UNTIL (IN OUT FN)
(DO ((PEEK (TELL IN :TYIPEEK) (TELL IN :TYIPEEK)))
((OR (NULL PEEK) (FUNCALL FN PEEK)))
(TELL OUT :TYO (TELL IN :TYI))))
(DEFUN EAT-STREAM-UNTIL (INSTREAM FUNCTION)
(DO ((INPUT (FUNCALL INSTREAM ':TYIPEEK) (FUNCALL INSTREAM ':TYIPEEK)))
((OR (NULL INPUT) (FUNCALL FUNCTION INPUT)))
(FUNCALL INSTREAM ':TYI)))
(DEFUN OLD-WRITE-BOX-INTO-FILE (FROM-BOX FILENAME)
(WITH-OPEN-FILE
(FILE-STREAM (FS:MERGE-PATHNAMES FILENAME *BOXER-PATHNAME-DEFAULT*) ':OUT)
(LET ((BOX-STREAM (MAKE-BOX-STREAM FROM-BOX)))
(FUNCALL FILE-STREAM ':LINE-OUT "-*- MODE: BOXER; -*-")
(STREAM-COPY-UNTIL-EOF BOX-STREAM FILE-STREAM)
':NOPRINT)))
(DEFUN OLD-READ-FILE-INTO-BOX (TO-BOX FILENAME)
(WITH-OPEN-FILE (INSTREAM (FS:MERGE-PATHNAMES FILENAME *BOXER-PATHNAME-DEFAULT*))
(LET ((FILE-ATTRIBUTES (FS:READ-ATTRIBUTE-LIST (FUNCALL INSTREAM ':PATHNAME) INSTREAM)))
(COND ((NEQ (CADR (MEMQ ':MODE FILE-ATTRIBUTES)) ':BOXER)
(FERROR "READ-FILE-INTO-BOX works only for BOXER files"))
(T
(EAT-STREAM-UNTIL INSTREAM #'STRT-BOX-CODE?)
(TELL TO-BOX :SET-CONTENTS-FROM-STREAM INSTREAM))))
(PROCESS-BOX-LOCAL-DEFINITIONS TO-BOX)
':NOPRINT))
(DEFUN FIX-BOXER-FILE (INFILE OUTFILE)
(WITH-OPEN-FILE (INSTREAM INFILE)
(WITH-OPEN-FILE (OUTSTREAM OUTFILE ':OUT)
(FUNCALL INSTREAM ':LINE-IN)
(FUNCALL OUTSTREAM ':LINE-OUT "-*- MODE: BOXER; -*-")
(FIX-BOXER-FILE-1 INSTREAM OUTSTREAM))))
(DEFUN FIX-BOXER-FILE-1 (INSTREAM OUTSTREAM)
(DO ()
((NOT (TELL INSTREAM :LISTEN)))
(STREAM-COPY-UNTIL INSTREAM OUTSTREAM
#'(LAMBDA (X) (MEMQ X '(#\ROMAN-I #\ROMAN-II #\ROMAN-III))))
(SELECTQ (TELL INSTREAM :TYI)
(#\ROMAN-I
(TELL OUTSTREAM :TYO *STRT-BOX-CODE*)
(FORMAT OUTSTREAM "~:S" (READ INSTREAM))
(TELL OUTSTREAM :TYO *STRT-ROW-CODE*))
(#\ROMAN-II
(TELL OUTSTREAM :TYO *STOP-ROW-CODE*)
(TELL OUTSTREAM :TYO *STOP-BOX-CODE*))
(#\ROMAN-III
(TELL OUTSTREAM :TYO *STOP-ROW-CODE*)
(TELL OUTSTREAM :TYO *STRT-ROW-CODE*)))))
;;;interface for the old versions of read/save
(DEFBOXER-FUNCTION BU:OLD-SAVE (FROM-BOX FILENAME)
(CHECK-DATA-BOX-ARG FILENAME)
(OLD-WRITE-BOX-INTO-FILE FROM-BOX (TELL FILENAME :TEXT-STRING)))
(DEFBOXER-FUNCTION BU:OLD-READ (TO-BOX FILENAME)
(OLD-READ-FILE-INTO-BOX TO-BOX (TELL FILENAME :TEXT-STRING)))
(DEFF PROCESS-BOX-LOCAL-DEFINITIONS 'IGNORE)